// *** CHARACTER OBJECT *** //
// Loads and controls the life, quests, movements and actions of the different NPCs on the map
//
// @project: GoldenShield
// @author: Kasper B. Jensen(kapper14@gmail.com)
// @version: 1.0

var character = {
    quests: [],                 //Array of all the different quest objects on the map
    paths: [],                  //Array of all the different path objects on the map
    characterLife: [],          //Holds the individual charecters life
    characterActions: [],       //Holds the different triggerIf actions for the character
    characterDieActions: [],    //Holds the character die action, given in XMAP
    showObject: null,           //Contains the HTML Charecter DOM object that are showing a quest right now, when no Quest is showing the value is null
    charecterPaused: false,     //Boolean value that tells if the game has been paused and stops the animation of the differnet charectorpaths
    standardLife: 10,           //Standard charecterlife
    shootingEnabled: true,      //Bolean value that tells if the characters can shoot
    targetingMinTime: 1500,     //Default minimum time the enimy should wait to shoot you
    targertingMaxTime: 4000,    //Default max time the enemy should wait to shoot you
    questIsShowing: false,      //Tells if a quest is beeing showed
    startUpQuest: null,         //Contains the characterID of startupquest
    
    //Resets object attributes back to normal!
    reset: function() {
        this.quests = [];
        this.paths = [];
        this.characterLife = [];
        this.characterDieActions = [];
        this.showObject = null;
        this.charecterPaused = false;
        this.standardLife = 10;
        this.shootingEnabled = true;
        this.targetingMinTime = 1500;
        this.targertingMaxTime = 4000;
        this.questIsShowing = false;
        
        character.removeQuests();
        character.resetIfAction();
        character.resetDieAction();
    },
    
    //Loads the different charecters on the map
    loadCharecters: function() {
        
        //Gives the NPCs life
        $('.NPC').each(function() {
            var id = $(this).attr("id");
            var charactersLength = character.characterLife.length;
            var objectExists = false;
            
            for(var i=0; i<charactersLength; i++) {
                var characterLifeObj = character.characterLife[i];
                
                if(characterLifeObj.object == id) {
                   objectExists = true;
                   if(characterLifeObj.life > 0 && $('#' + id).hasClass('shoot')) {
                    //Adds a lifebar to the NPC
                    guiObject.addEvilLifeBar(id, characterLifeObj.life);
                   } 
                   break;
                }
            }
            
            if(!objectExists) {
                character.characterLife.push({object: id, life: character.standardLife});
                if( $('#' + id).hasClass('shoot')) {
                    //Adds a lifebar to the NPC
                    guiObject.addEvilLifeBar(id, character.standardLife);
                }
            }
        })
    },
    
    //Removes 1 life from given character in paremeter and makes him dead when he has no more!
    damage: function(id) {
            var charactersLength = character.characterLife.length;
            
            for(var i=0; i<charactersLength; i++) {
                var characterLifeObj = character.characterLife[i];
                
                
                if(characterLifeObj.object == id) {
                    if(!$('#' + id).hasClass('immortal')) {
                        if(characterLifeObj.life > 0) {
                            character.characterLife[i].life--
                            guiObject.updateEvilLifeBar(id, character.characterLife[i].life);
                        } else {
                            
                            //If chracter is did
                            if(!$('#' + id).hasClass('isDid')) {
                                
                                //Chracter fades out
                                $('#' + characterLifeObj.object).fadeOut(function() {
                                    $(this).remove();
                                })
                                
                                //Die action is running
                                if($('#' + id).hasClass('dieAction')) {
                                    character.runDieAction(id);
                                    $(this).removeClass('dieAction');
                                }
                                
                                //A kill is been added to player
                                player.newKill();
                                
                                //Lifebar is being removed
                                guiObject.removeLifeBar(id);
                                
                                //The chacter is now did 
                                $('#' + id).addClass('isDid');                               
                            }
                        }
                    }
                    break;
                }
            }
    },
    
    //Cheks if the given character is dead. True/False is being returned
    isDid: function(object) {
        var charactersLength = character.characterLife.length;
            for(var i=0; i<charactersLength; i++) {
                var characterLifeObj = character.characterLife[i];
                if(characterLifeObj.object == object) {
                    if(characterLifeObj.life == 0) {
                        return true;
                    } else {
                        return false;
                    }
                    break;   
                }

            }
    },
    
    //Updates damaged charecters when map is loaded
    updateDamage: function() {
        var charactersLength = character.characterLife.length;
            
            for(var i=0; i<charactersLength; i++) {
                var characterLifeObj = character.characterLife[i];
                var characterObject = '#' + character.characterLife[i].object;
                if(characterLifeObj.life == 0) {
                        $(characterObject).remove();
                }   
            }
    },
    
    //Moves the given character to the given position
    charGoTo: function(x,y, object, speed, func) {
        $('#' + object).animate({left: x + "px", top: y + "px"}, speed, func);
    },
    
    //Loads the charector object and path into the paths array
    loadPath: function(object, path) {
        this.paths.push({object: object, number: 0, path: path, waitTimer: 0});
        
    },
    
    //Loads the characters quests into the the quets array
    loadQuests: function(object, quests) {
        this.quests.push({object: object, quests: quests, showNumber: 0});
    },
    
    //Adds a new quest line to the given charecter object
    addQuest: function(object, msg) {
        var questLength = this.quests.length;
        var objectExist = false;
        var objectQuests;
        var questObject;
        var indexNumber;
        
        //If no parameters given, return false and give a message
        if(!object || !msg) {
            console.log("No object or message is given in character.addQuest!");
            return false;
        }
        
        for(var i=0; i<questLength; i++) {
            questObject = this.quests[i];
            
            if(questObject.object == object) {
                objectExist = true;
                indexNumber = i;
                break;
            }
        }
        
        if(objectExist) {
            var msgObj = {0: msg}
            this.quests[indexNumber].quests.push(msgObj);
        } else {
            var msgObj = [{0: msg}];
            var questPush = {object: object, quests: msgObj, showNumber: 0};
            this.quests.push(questPush);
            $('#' + object).addClass('quest');
        }
        
        return true;
    },
    
    //Deletes a charecters quest
    delQuest: function(object) {
        var questLength = this.quests.length;
        
        if(!object) {
            console.log("No object given in character.delQuest!");
            return false;
        }
        
        for(var i=0; i<questLength; i++) {
            questObject = this.quests[i];
            
            if(questObject.object == object) {
                this.quests.splice(i,1);
            }
        }
        return true;
    },
    
    //Sets the map startup quest
    setStartupQuest: function(characterID) {
        if(!characterID) {
            return false;
        }
        
        this.startUpQuest = characterID;
        return true;
    },
    
    //Runs the given startup quest
    runStartupQuest: function() {
        if(this.startUpQuest) {
            this.showQuest(this.startUpQuest, false);
        } 
    },
    
    //Loads the different triggerIf actions into an array
    loadAction: function(action) {
        this.characterActions.push(action);
    },
    
    //Trigger the if action
    triggerIfAction: function(object) {
        var actionsLength = this.characterActions.length;
        for(var i=0; i<actionsLength;i++) {
            var triggerIfObject = this.characterActions[i].triggerObject;
            if(triggerIfObject == object) {
                
                //Loads the actions for the object into variables
                var requereNumber = this.characterActions[i].requireNumber;
                var requerement = this.characterActions[i].requerement;
                var doAction = this.characterActions[i].action;
                var elseAction = this.characterActions[i].elseDo;
                var operator = this.characterActions[i].operator;
                
                // '+' = bigger then, '-' smaller then, '=' = equality 
                switch(operator) {
                    case "+":
                        if(player[requerement] > requereNumber) {
                            eval(doAction);
                        } else {
                            eval(elseAction);
                        }
                    break;
                    case "-":
                        if(player[requerement] < requereNumber) {
                            eval(doAction);
                        } else {
                            eval(elseAction);
                        }
                    break;
                    case "+=":
                        if(player[requerement] >= requereNumber) {
                            eval(doAction);
                        } else {
                            eval(elseAction);
                        }
                    break;
                    case "-=":
                        if(player[requerement] <= requereNumber) {
                            eval(doAction);
                        } else {
                            eval(elseAction);
                        }
                    break;
                    case "=":
                        if(player[requerement] == requereNumber) {
                            eval(doAction);
                        } else {
                            eval(elseAction);
                        }
                    break;
                }
            }
        }
    },
    
    //Empty the action array
    resetIfAction: function() {
        this.characterActions = [];
    },
    
    //Empty the die action array
    resetDieAction: function() {
        this.characterDieActions = [];
    },
    
    //Loads the characters die actions
    loadDieAction: function(action) {
        this.characterDieActions.push(action);
    },
    
    //Run the die action for the given character
    runDieAction: function(object) {
        var dieActionLength = this.characterDieActions.length;
        for(var i=0; i<dieActionLength; i++) {
            var dieAction = this.characterDieActions[i];
            if(object == dieAction.object) {
                if(dieAction.action[0]) {
                    eval(dieAction.action[0]);
                }
            }
        }
    },
    
    //Empty the quest array
    removeQuests: function() {
        this.quests = [];
    },
    
    //Shows the quest for the given player. 
    //Key tells if enter key is used when the function is called.
    showQuest: function(object, key) {
        if(!guiObject.writingText) { //If the guiObject not is writing text to screen
           
           var questsLength = this.quests.length;
                    
             for(var i=0; i<questsLength; i++) {
                if(this.quests[i].object == object) {
                       
                    //Disables shooting when quist is showed
                    this.shootingEnabled = false;
                    if(this.isDid(object)) { //Check if the character is did
                        break;
                    }
                
                    if(key) { //If enter key is used, we display the next message for the quest
                        this.quests[i].showNumber++;
                    }
                
                    var number = this.quests[i].showNumber;
                    var texts = this.quests[i].quests.length;
                    this.showObject = object;

                    if(number < texts) { //Shows the next message if there are more texts for the quest
                        this.questIsShowing = true;
                        var message = object + ": " + character.quests[i].quests[number][0];
                        guiObject.showMessage(message);
                    }
                
                    if(number == texts) { //Remove the message bugs, if the text for the quest is done
                        character.shootingEnabled = true;
                        this.questIsShowing = false;
                        guiObject.removeMessage();
                        character.showObject = null;
                        $('#' + object).removeClass('quest');
                        this.quests.splice(i,1);
                    }
                    break;
            }
        }
      }
        
    },
    
    //Paused the NPC character action
    charecterPause: function() {
        this.charecterPaused = true;
        this.shootingEnabled = false;
    },
    
    //Unpause the NPC charecter action
    charecterUnPause: function() {
        this.charecterPaused = false;
        this.shootingEnabled = true;
    },
    
    //Start the shooting mechanisme 
    startShoting: function() {
        var id;
        if($('.shoot').attr('id')) {
            $('.shoot').each(function() {
            id = $(this).attr("id");
                character.shoot(id);
            });
        } else {
            this.shootingEnabled = false;
        }
  
    },
    
    //Shoot function that shoots at the player
    shoot: function(charactorId, targMinTime, targMaxTime, shootTime) {
        var id = "Bullet" + Math.round(Math.random() * 100000);
        
        //The characters cordinates
        var charactorX = parseInt($('#'+charactorId).css("left")) + 8;
        var charactorY = parseInt($('#'+charactorId).css("top")) + 20;
        var animation = false;
        
        //If the character has a shoot GIF animation
        if($('#'+charactorId).hasClass("shootAnimate")) {
            var shootAnimationSrc = $('#'+charactorId).css("backgroundImage");
            var normalSrc = shootAnimationSrc;
            var regExp = new RegExp(".png", "g");
            shootAnimationSrc = shootAnimationSrc.replace(regExp, ".shoot.gif");
            animation = true;
        }
        
        if($('#' + charactorId).attr('amo')) {
            var bullet = $('#' + charactorId).attr('amo');
        } else {
            var bullet = "fireball";
        }
        
        var bulletGif = "img/shootingObjects/" + bullet + ".gif";
        
            var shootFunc = function() {
                if(!charactorX == 0 && !charactorY == 0) { //Is the character positioned on the map
                
                //Takes the player cordinates
                var playerX = (player.x + player.width/2); 
                var playerY = (player.y + player.height/2);
                
                if(!shootTime) { // If not shoot time has been set, shootTime is 1 sec.
                    shootTime = 1000;
                }
                
                //Character is ready to shoot
                if(character.shootingEnabled) {
                if(animation) { //Loads the character aniamtion
                    $('#'+charactorId).css({backgroundImage: shootAnimationSrc});
                }
                $('#'+charactorId).fadeTo(shootTime, 0.8,function() { //Fades the character a little
                    $('#'+charactorId).css({backgroundImage: normalSrc}); //Character back to normal
                    
                    //Fireball is chreated
                    $('#mapContent').append("<div id='" + id + "' style='width: 20px; height: 20px; background-image: url(" + bulletGif + "); background-repeat: no-repeat; position: absolute; z-index: 200; left:" + charactorX + "px; top:" + charactorY +"px;' class='colobject trigger damage hasPath " + id + "Path bullet'></div>");
                    
                    //Shoot at player and start the shooting all over again
                    sound.playSoundByObjectID(charactorId);
                    $('#'+id).animate({left: playerX, top: playerY}, shootTime, function() {
                        $('#'+id).fadeOut(500, function() { 
                            $(this).remove();
                        });
                        
                        $('#'+charactorId).fadeTo(shootTime, 1, function() {
                            character.shoot(charactorId, targMinTime, targMaxTime, shootTime);
                        });
                    });
                    
                });
                
                } else { //If not shooting is enabled, call the shooting mechanisme again 
                    character.shoot(charactorId, targMinTime, targMaxTime, shootTime);     
                }
            }
        }
        
        if(!targMinTime && !targMaxTime) { //If no targeting time has been given, use defaults
            targMinTime = this.targetingMinTime;
            targMaxTime = this.targertingMaxTime;
        }
        
        //Sets the shoot timer functions
        var timer = Math.round(targMinTime + Math.random() * targMaxTime);
        setTimeout(shootFunc, timer);
  }   
    
}